generic
   type individu (<>) is private;
   type cercle (<>) is private;
   type texte (<>) is private;
   type mur (<>) is private;
   with function creer (m : individu) return mur is <>;
   with function afficher (mu : mur; m : individu; t : texte; i : natural) return mur is <>;
   with function est_defini (mu : mur; i : natural) return boolean is <>;
   with function auteur (mu : mur; i : natural) return individu is <>;
   with function "<=" (m, n : individu) return boolean is <>;
   with function "<=" (c, d : cercle) return boolean is <>;

package Sigma is
   type Model is private;
   function creer return Model;

-----------------------------------------------------------------------------------------------
------------------- LES INDIVIDUS DE LA COMMUNAUTE---------------------
-----------------------------------------------------------------------------------------------

   function inscrire (x : Model; n : individu) return Model;
   function est_inscrit (x : Model; n : individu) return boolean;
   function nombre_inscrits (x : Model) return natural;
   function ieme_inscrit (x : Model; i : natural) return individu;
   function bloquer (x : Model; m : individu; n : individu) return Model;
   function debloquer (x : Model; m : individu; n : individu) return Model;
   function est_bloque (x : Model; m : individu; n : individu) return boolean;

------------------------------------------------------------------------------
------------------- LES CERCLES D'UN INDIVIDU --------------------------------
------------------------------------------------------------------------------

   function est_cercle_de (x : Model; n : individu; c : cercle) return boolean;
   function ajouter_cercle (x : Model; n : individu; c : cercle) return Model;
   function retirer_cercle (x : Model; n : individu; c : cercle) return Model;
   function nombre_cercles_de (x : Model; n : individu) return natural;
   function ieme_cercle (x : Model; n : individu; i : natural) return cercle;

-----------------------------------------------------------------------------------------------
------------------- LES MEMBRES D'UN CERCLE -------------------------------
-----------------------------------------------------------------------------------------------

   function est_membre_de (x : Model; m : individu; c : cercle; n : individu) return boolean;
   function ajouter_membre (x : Model; n : individu; c : cercle; p : individu) return Model;
   function retirer_membre (x : Model; n : individu; c : cercle; p : individu) return Model;
   function nombre_membres_de (x : Model; n : individu; c : cercle) return natural;
   function ieme_membre (x : Model; n : individu; c : cercle; i : natural) return individu;

-----------------------------------------------------------------------------------------------
------------------- POSTS ET COMMENTAIRES ----------------------------------
---------------------------------------------------------------------------------------
   function poster(x : Model; n : individu; c : cercle; t : texte) return Model;
   function commenter(x : Model; n : individu; i : natural; t : texte) return Model;
   function nombre_posts(x : Model) return natural;
   function consulter(x : Model; n : individu) return mur;

private
   type Model_Builder is (creer, inscrire, bloquer, debloquer, ajouter_cercle, retirer_cercle, ajouter_membre, retirer_membre, poster, commenter);
   type Model_Term (The_Builder : Model_Builder);
   type Model is access Model_Term;
   type Model_Term (The_Builder : Model_Builder) is record
      case The_Builder is
         when CREER => null;
         when inscrire => inscrire_x : Model; inscrire_n : access individu;
         when bloquer => bloquer_x : Model; bloquer_m : access individu; bloquer_n : access individu;
         when debloquer => debloquer_x : Model; debloquer_m : access individu; debloquer_n : access individu;
         when ajouter_cercle => ajouter_cercle_x : Model; ajouter_cercle_n : access individu; ajouter_cercle_c : access cercle;
         when retirer_cercle => retirer_cercle_x : Model; retirer_cercle_n : access individu; retirer_cercle_c : access cercle;
         when ajouter_membre => ajouter_membre_x : Model; ajouter_membre_n : access individu; ajouter_membre_c : access cercle; ajouter_membre_p : access individu;
         when retirer_membre => retirer_membre_x : Model; retirer_membre_n : access individu; retirer_membre_c : access cercle; retirer_membre_p : access individu;
         when poster => poster_x : Model; poster_n : access individu; poster_c : access cercle; poster_t : access texte;
         when commenter => commenter_x : Model; commenter_n : access individu; commenter_i : access natural; commenter_t : access texte;
      end case;
   end record;
end Sigma;

